package com.liyunc.demo.service;
/**
 * Copyright (c) 2018-2022 ThunderSoft
 * All Rights Reserved by Thunder Software Technology Co., Ltd and its affiliates.
 * You may not use, copy, distribute, modify, transmit in any form this file
 * except in compliance with ThunderSoft in writing by applicable law.
 */

import com.liyunc.demo.model.dto.UserInfoDto;
import com.liyunc.demo.model.entity.RoleInfo;
import com.liyunc.demo.model.entity.UserInfo;

import com.liyunc.demo.service.base.BaseService;
import com.liyunc.demo.utils.ToDtoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.security.RolesAllowed;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author liyuncong
 * @version 1.0
 * @file
 * @brief
 * @details
 * @date 2022-02-16
 *
 * Edit History
 * ----------------------------------------------------------------------------
 * DATE                     NAME               DESCRIPTION
 * 2022-02-16               liyuncong        Created
 */
@Service
public class UserService extends BaseService implements UserDetailsService {

    /**
     * 数据库明文，所以需加密密码.
     */
    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 获取所有用户.
     */
    public List<UserInfoDto> getUserList(final int startIndex, final int pageSize) {
        Sort sort = Sort.by(Sort.Direction.ASC, "id");
        Pageable pageable = PageRequest.of(startIndex, pageSize, sort);
        return userInfoRepository
            .findAll(pageable)
            .stream()
            .map(ToDtoUtils::forInfoEntity)
            .collect(Collectors.toList());
    }


    /**
     * 通过id获取单个用户.
     */
    public Optional<UserInfo> getSingleUser(long id) {
        return Optional.of(userInfoRepository
            .getById(id));
    }

    /**
     * 创建用户.
     */
    @Transactional
    @RolesAllowed({"ROLE_ADMIN"})
    public Optional<UserInfoDto> createUser(UserInfoDto userDto) {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername(userDto.getUsername());
        userInfo.setPassword("123456");
        userInfo.setKey(1);
        UserInfo createInfo = userInfoRepository.save(userInfo);
        return Optional.of(createInfo).map(ToDtoUtils::forInfoEntity);
    }

    /**
     * 删除用户.
     */
    @Transactional
    @RolesAllowed({"ROLE_ADMIN"})
    public void deleteUser(long userId) {
        userInfoRepository.deleteById(userId);
    }

    /**
     * security 加载用户.
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserInfo userInfo = userInfoRepository.findByUsername(username);
        List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
        if (userInfo != null) {
            Set<RoleInfo> roles = roleInfoRepository.findAllByUserId(userInfo.getId());
            if (!roles.isEmpty()) {
                for (RoleInfo role : roles) {
                    GrantedAuthority grantedAuthority;
                    if (null != role) {
                        grantedAuthority =
                            new SimpleGrantedAuthority(role.getName());
                    } else {
                        grantedAuthority =
                            new SimpleGrantedAuthority("ROLE_USER");
                    }
                    grantedAuthorities.add(grantedAuthority);
                }
            }
            return new User(
                userInfo.getUsername(),
                passwordEncoder.encode(userInfo.getPassword()),
                grantedAuthorities);
        } else {
            throw new UsernameNotFoundException(username + "do not exist!");
        }
    }
}
